// bitmap 位向量
// set 设置基础列表(item 项不唯一)
// checkBit 检查基础列表中，是否存在这个值（同时输出个数）（个数<=3）
//

class Bitmap {
  constructor(bitsize = 10) {
    let byteSize = bitsize >> 2 // 2位来存数据 （0为无，其他为有，且为个数）
    let remainder = bitsize & 0x03 // 3
    let boxSize = byteSize + (remainder ? 1 : 0)

    this.buf = Buffer.alloc(boxSize, 0, 'binary')
  }

  bitSet(number, count) {
    let { binaryValue: data, binaryIndex, byteIndex } = this.getBit(number)

    // 对应 位 +1 (排除大于3的情况)
    if (data + count > 3) {
      console.log(
        `存数为:${number}时出现错误,单个数最大存储个数为：3，需要存储个数：${count}，目前已存储${data}`
      )
      return
    } else {
      this.buf[byteIndex] += count << binaryIndex
    }
  }

  checkBit(number) {
    let { binaryValue } = this.getBit(number)
    console.log(`数字${number}个数为: ${binaryValue}`)
    return binaryValue
  }

  getBit(number) {
    let byteIndex = (number >> 2) - 1

    let remainder = number & 0x03

    // 定位出-字节中存数据的 x 位 （x-1位）
    let byteInBinaryIndex = 0

    // 存在余数的情况下 字节定位出的索引值加一
    if (remainder) {
      byteIndex += 1
      byteInBinaryIndex = (4 - remainder) * 2
    }

    let byte = this.buf[byteIndex]
    // 找出 这个 2位 - 值
    let data = (byte & (3 << byteInBinaryIndex)) >> byteInBinaryIndex

    return { binaryValue: data, binaryIndex: byteInBinaryIndex, byteIndex }
  }
}
let bitMap = new Bitmap(50000000)
// set

bitMap.bitSet(1, 2)
bitMap.bitSet(2, 3)
bitMap.bitSet(3, 3)
bitMap.bitSet(4, 1)
bitMap.bitSet(5, 3)
bitMap.bitSet(6, 3)
bitMap.bitSet(7, 3)
bitMap.bitSet(8, 4)
bitMap.bitSet(100, 1)
bitMap.bitSet(120, 1)
bitMap.bitSet(129, 2)

// check
bitMap.checkBit(1)
bitMap.checkBit(2)
bitMap.checkBit(4)
bitMap.checkBit(8)
bitMap.checkBit(100)
bitMap.checkBit(120)
bitMap.checkBit(129)

console.log('-------')
console.log(bitMap)
